package br.com.jk.valealim.cartaovenda;

import br.com.jk.util.Util;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author camilo
 */
public class CartaoVendaTableModel extends AbstractTableModel {

  public static final String COLUMN_NAME_ID = "Id";
  public static final String COLUMN_NAME_CARTAO = "Cartão";
  public static final String COLUMN_NAME_CUPOMNUM = "Cupom";
  public static final String COLUMN_NAME_DATA_CUPOM = "Data Cupom";
  public static final String COLUMN_NAME_DATA_AUTORIZACAO = "Data Aut.";
  public static final String COLUMN_NAME_VALOR_VENDA = "Valor";
  public static final String COLUMN_NAME_PLANO = "Plano";
  public static final String COLUMN_NAME_AUTORIZACAO = "Aut.";
  public static final int COLUMN_COD_ID = 6;
  public static final int COLUMN_COD_CARTAO = 7;
  public static final int COLUMN_COD_CUPOMNUM = 3;
  public static final int COLUMN_COD_DATA_CUPOM = 2;
  public static final int COLUMN_COD_DATA_AUTORIZACAO = 0;
  public static final int COLUMN_COD_VALOR_VENDA = 4;
  public static final int COLUMN_COD_PLANO = 5;
  public static final int COLUMN_COD_AUTORIZACAO = 1;
  public static final int COLUMN_QTD = 6;
  private static final long serialVersionUID = 1L;
  /**
   * Essa lista armazenará os objetos do tipo {@link NfeItens} atualmente exibidos na tabela.
   */
  private List<CartaoVenda> lstCartao;

  // ==============================================================  
  // Construtores.  
  // ==============================================================  
  /**
   * Constutor que simplesmente instancia o nosso {@link List} que usaremos para guardar os valores.
   */
  public CartaoVendaTableModel() {
    // no construtor, instanciamos o List  
    lstCartao = new ArrayList<>();
  }

  /**
   * Criamos um construtor de conveniência para já popular a lista.
   *
   * @param lista a lista de produtos a ser adicionada.
   */
  public CartaoVendaTableModel(List<CartaoVenda> lista) {
    this();
    lstCartao.addAll(lista);
  }

  // ==============================================================  
  // Métodos implementados.  
  // ==============================================================  
  /**
   * Representa o tipo de dados exibidos nas colunas
   *
   * @param coluna
   * @return
   */
  @Override
  public Class<?> getColumnClass(int coluna) {
    if (coluna == COLUMN_COD_ID || coluna == COLUMN_COD_CUPOMNUM || coluna == COLUMN_COD_AUTORIZACAO) {
      return int.class;
    } else if (coluna == COLUMN_COD_DATA_AUTORIZACAO || coluna == COLUMN_COD_DATA_CUPOM) {
      return Date.class;
    } else if (coluna == COLUMN_COD_VALOR_VENDA) {
      return BigDecimal.class;
    } else {
      return String.class;
    }
  }

  /**
   * Retorna o número de colunas
   *
   * @return
   */
  @Override
  public int getColumnCount() {
    return COLUMN_QTD;
  }

  /**
   * Retorna o nome de cada coluna
   *
   * @param coluna
   * @return
   */
  @Override
  public String getColumnName(int coluna) {
    switch (coluna) {
      case COLUMN_COD_ID:
        return COLUMN_NAME_ID;
      case COLUMN_COD_CUPOMNUM:
        return COLUMN_NAME_CUPOMNUM;
      case COLUMN_COD_DATA_CUPOM:
        return COLUMN_NAME_DATA_CUPOM;
      case COLUMN_COD_DATA_AUTORIZACAO:
        return COLUMN_NAME_DATA_AUTORIZACAO;
      case COLUMN_COD_VALOR_VENDA:
        return COLUMN_NAME_VALOR_VENDA;
      case COLUMN_COD_AUTORIZACAO:
        return COLUMN_NAME_AUTORIZACAO;
      case COLUMN_COD_PLANO:
        return COLUMN_NAME_PLANO;
      default:
        return "";
    }
  }

  /**
   * Retorna a quantidade de linhas.
   *
   * @return
   */
  @Override
  public int getRowCount() {
    return lstCartao.size();
  }

  /**
   * Retorna o valor de determinada célula.
   *
   * @param linha
   * @param coluna
   * @return
   */
  @Override
  public Object getValueAt(int linha, int coluna) {
//    Cria-se um objeto com base na linha solicitada
    CartaoVenda c = lstCartao.get(linha);

    switch (coluna) {
      case COLUMN_COD_ID:
        return c.getId();
      case COLUMN_COD_VALOR_VENDA:
        return c.getValorVenda();
      case COLUMN_COD_CUPOMNUM:
        return c.getCupomNum();
      case COLUMN_COD_DATA_CUPOM:
        return c.getDataCupom();
      case COLUMN_COD_DATA_AUTORIZACAO:
        return c.getDataAutorizacao();
      case COLUMN_COD_PLANO:
        return c.getPlano();
      case COLUMN_COD_AUTORIZACAO:
        return c.getAutorizacao();
      default:
        return null; // não ocorrerá devido a quantidade de colunas
    }
  }

  /**
   * Define as células que poderão ser editadas.
   *
   * @param rowIndex
   * @param columnIndex
   * @return
   */
  @Override
  public boolean isCellEditable(int rowIndex, int columnIndex) {
    // nesse caso, todas as células não são editáveis  
    return false;
  }

  /**
   * Define o valor para a célula
   *
   * @param valor - Novo valor para a célula
   * @param linha - Linha onde está a célula a ser alterada
   * @param coluna Coluna onde está a célula a ser alterada
   */
  @Override
  public void setValueAt(Object valor, int linha, int coluna) {
//    Cria-se um objeto com base na linha solicitada
    CartaoVenda c = lstCartao.get(linha);
//verifica-se qual será a coluna a ser alterada
    switch (coluna) {
      case COLUMN_COD_CUPOMNUM:
        c.setCupomNum(Integer.parseInt(valor.toString()));
        break;
      case COLUMN_COD_DATA_AUTORIZACAO:
        c.setDataAutorizacao(Util.formatDataSToD(valor.toString()));
        break;
      case COLUMN_COD_DATA_CUPOM:
        c.setDataCupom(Util.formatDataSToD(valor.toString()));
        break;
      case COLUMN_COD_ID:
        c.setId(Integer.parseInt(valor.toString()));
        break;
      case COLUMN_COD_VALOR_VENDA:
        c.setValorVenda(new BigDecimal(valor.toString()));
        break;
      case COLUMN_COD_AUTORIZACAO:
        c.setAutorizacao(Integer.parseInt(valor.toString()));
        break;
      case COLUMN_COD_PLANO:
        c.setPlano(valor.toString());
        break;
    }

    // é importante notificar os listeners a cada alteração  
    fireTableDataChanged();
  }

  // ==============================================================  
  // Até aqui seria o mínimo necessário para um TableModel funcional, mas  
  // ainda não há métodos para adicionar, remover ou resgatar objetos. Vamos  
  // criá-los.  
  // ==============================================================  
  /**
   * Adiciona um novo registro e notifica os listeners que um novo registro foi adicionado.
   */
  public void adiciona(CartaoVenda classe) {
    lstCartao.add((CartaoVenda) classe);
    // informamos os listeners que a linha (size - 1) foi adicionada  
    fireTableRowsInserted(lstCartao.size() - 1, lstCartao.size() - 1);
  }

  /**
   * Similar ao {@link #adiciona()}, porém para remover. Recebe o índice do registro a ser removido. Se não
   * souber o índice, use o método {@link #getIndice()} antes.
   */
  public void remove(int indice) {
    lstCartao.remove(indice);
    fireTableRowsDeleted(indice, indice);
  }

  /**
   * Retorna o índice de determinado registro.
   */
  public int getIndice(CartaoVenda m) {
    return lstCartao.indexOf(m);
  }

  /**
   * Adiciona todos os registros na lista à este modelo.
   */
  public void adicionaLista(List<?> lista) {
    int i = lstCartao.size();
    lstCartao.addAll((List<CartaoVenda>) lista);
    fireTableRowsInserted(i, i + lista.size());
  }

  /**
   * Esvazia a lista.
   */
  public void limpaLista() {
    int i = lstCartao.size();
    lstCartao.clear();
    fireTableRowsDeleted(0, i - 1);
  }
}
